/*
 * Copyright (c) 2012, marco.tamburelli@gmail.com
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met: 
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution. 
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * The views and conclusions contained in the software and documentation are those
 * of the authors and should not be interpreted as representing official policies, 
 * either expressed or implied, of the CometMI Project.
 */
package org.cometmi.gwt.shared.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

import org.cometmi.gwt.shared.exceptions.InvalidArgumentException;
import org.cometmi.gwt.shared.request.ptypes.BooleanParam;
import org.cometmi.gwt.shared.request.ptypes.ByteParam;
import org.cometmi.gwt.shared.request.ptypes.CharacterParam;
import org.cometmi.gwt.shared.request.ptypes.DateParam;
import org.cometmi.gwt.shared.request.ptypes.DoubleParam;
import org.cometmi.gwt.shared.request.ptypes.FloatParam;
import org.cometmi.gwt.shared.request.ptypes.IntegerParam;
import org.cometmi.gwt.shared.request.ptypes.LongParam;
import org.cometmi.gwt.shared.request.ptypes.ObjectParam;
import org.cometmi.gwt.shared.request.ptypes.ObjectVarParam;
import org.cometmi.gwt.shared.request.ptypes.Param;
import org.cometmi.gwt.shared.request.ptypes.ShortParam;
import org.cometmi.gwt.shared.request.ptypes.StringParam;

import com.google.gwt.user.client.rpc.IsSerializable;

public class UtilityFunctions
{
	public static final Random RANDOM = new Random();

	public static String generateUniqueId()
	{
		return Integer.toString(UtilityFunctions.RANDOM.nextInt(1679615), 36);
	}

	public static List<Param<?>> copyArguments(List<Param<?>> args)
	{
		ArrayList<Param<?>> copy = new ArrayList<Param<?>>();

		for (Param<?> p : args)
			copy.add(p.copy());

		return copy;
	}

	public static List<Param<?>> createParameters(Object[] params) throws InvalidArgumentException
	{
		ArrayList<Param<?>> _params = new ArrayList<Param<?>>();

		for (Object p : params)
			_params.add(createParameter(p));

		return _params;
	}

	public static Param<?> createParameter(Object p) throws InvalidArgumentException
	{
		if (p instanceof Boolean)
		{
			BooleanParam _p = new BooleanParam();
			_p.setValue((Boolean) p);

			return _p;
		}
		else if (p instanceof Byte)
		{
			ByteParam _p = new ByteParam();
			_p.setValue((Byte) p);

			return _p;
		}
		else if (p instanceof Character)
		{
			CharacterParam _p = new CharacterParam();
			_p.setValue((Character) p);

			return _p;
		}
		else if (p instanceof Date)
		{
			DateParam _p = new DateParam();
			_p.setValue((Date) p);

			return _p;
		}
		else if (p instanceof Double)
		{
			DoubleParam _p = new DoubleParam();
			_p.setValue((Double) p);

			return _p;
		}
		else if (p instanceof Float)
		{
			FloatParam _p = new FloatParam();
			_p.setValue((Float) p);

			return _p;
		}
		else if (p instanceof Integer)
		{
			IntegerParam _p = new IntegerParam();
			_p.setValue((Integer) p);

			return _p;
		}
		else if (p instanceof Long)
		{
			LongParam _p = new LongParam();
			_p.setValue((Long) p);

			return _p;
		}
		else if (p instanceof Short)
		{
			ShortParam _p = new ShortParam();
			_p.setValue((Short) p);

			return _p;
		}
		else if (p instanceof String)
		{
			StringParam _p = new StringParam();
			_p.setValue((String) p);

			return _p;
		}
		else if (p instanceof ProxyBase)
		{
			ObjectVarParam _p = new ObjectVarParam();
			_p.init(ProxyBase.getObjectId((ProxyBase) p));

			return _p;
		}
		else if (p instanceof IsSerializable)
		{
			ObjectParam _p = new ObjectParam();
			_p.setValue((IsSerializable) p);

			return _p;
		}
		else
			throw new InvalidArgumentException(p.getClass().getName() + " is a type that cannot be serialized.");
	}
}
